﻿#region Copyright Notice
// 
// 
//  
//  Copyright (c) 2009-2011 Anindya Chatterjee
//  
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//  
//      http://www.apache.org/licenses/LICENSE-2.0
//  
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
// 
// 
#endregion
using System;

namespace AbstractClass.Threading.Tasks
{
    /// <summary>
    /// Represents an operation which does not return any result upon completion.
    /// </summary>
    public class Work : Job<WorkCompletionStatus>
    {
        private readonly Action _action;

        /// <summary>
        /// Initializes a new instance of the <see cref="Work"/> class.
        /// </summary>
        /// <param name="action">The action to run.</param>
        public Work(Action action)
        {
            _action = action;
        }

        /// <summary>
        /// Begins an asynchronous operation.
        /// </summary>
        /// <param name="callback">The <see cref="AsyncCallback"/> delegate.</param>
        /// <param name="state">The state object for this operation.</param>
        /// <returns>The status of the asynchronous operation.</returns>
        protected internal override IAsyncResult BeginInvoke(AsyncCallback callback, object state)
        {
            return _action.BeginInvoke(callback, state);
        }

        /// <summary>
        /// Ends an asynchronous operation.
        /// </summary>
        /// <param name="asyncResult">The status of this asynchronous operation.</param>
        /// <returns>Completion status of the operation.</returns>
        protected internal override WorkCompletionStatus EndInvoke(IAsyncResult asyncResult)
        {
            _action.EndInvoke(asyncResult);
            return WorkCompletionStatus.Successful;
        }

        /// <summary>
        /// Executes the operation.
        /// </summary>
        /// <returns>Completion status of the operation.</returns>
        protected internal override WorkCompletionStatus Invoke()
        {
            _action.Invoke();
            return WorkCompletionStatus.Successful;
        }
    }

    /// <summary>
    /// Represents an operation which does not return any result upon completion.
    /// </summary>
    /// <typeparam name="T">The type of the first argument.</typeparam>
    public class Work<T> : Job<WorkCompletionStatus>
    {
        private readonly Action<T> _action;
        private readonly T _arg;

        /// <summary>
        /// Initializes a new instance of the <see cref="Work&lt;T&gt;"/> class.
        /// </summary>
        /// <param name="action">The action to run.</param>
        /// <param name="arg">The first argument.</param>
        public Work(Action<T> action, T arg)
        {
            _action = action;
            _arg = arg;
        }

        /// <summary>
        /// Begins an asynchronous operation.
        /// </summary>
        /// <param name="callback">The <see cref="AsyncCallback"/> delegate.</param>
        /// <param name="state">The state object for this operation.</param>
        /// <returns>The status of the asynchronous operation.</returns>
        protected internal override IAsyncResult BeginInvoke(AsyncCallback callback, object state)
        {
            return _action.BeginInvoke(_arg, callback, state);
        }

        /// <summary>
        /// Ends an asynchronous operation.
        /// </summary>
        /// <param name="asyncResult">The status of this asynchronous operation.</param>
        /// <returns>Completion status of the operation.</returns>
        protected internal override WorkCompletionStatus EndInvoke(IAsyncResult asyncResult)
        {
            _action.EndInvoke(asyncResult);
            return WorkCompletionStatus.Successful;
        }

        /// <summary>
        /// Executes the operation.
        /// </summary>
        /// <returns>Completion status of the operation.</returns>
        protected internal override WorkCompletionStatus Invoke()
        {
            _action.Invoke(_arg);
            return WorkCompletionStatus.Successful;
        }
    }

    /// <summary>
    /// Represents an operation which does not return any result upon completion.
    /// </summary>
    /// <typeparam name="T1">The type of the first argument.</typeparam>
    /// <typeparam name="T2">The type of the second argument.</typeparam>
    public class Work<T1, T2> : Job<WorkCompletionStatus>
    {
        private readonly Action<T1, T2> _action;
        private readonly T1 _arg1;
        private readonly T2 _arg2;

        /// <summary>
        /// Initializes a new instance of the <see cref="Work&lt;T1, T2&gt;"/> class.
        /// </summary>
        /// <param name="action">The action to run.</param>
        /// <param name="arg1">The first argument.</param>
        /// <param name="arg2">The second argument.</param>
        public Work(Action<T1, T2> action, T1 arg1, T2 arg2)
        {
            _action = action;
            _arg1 = arg1;
            _arg2 = arg2;
        }

        /// <summary>
        /// Begins an asynchronous operation.
        /// </summary>
        /// <param name="callback">The <see cref="AsyncCallback"/> delegate.</param>
        /// <param name="state">The state object for this operation.</param>
        /// <returns>The status of the asynchronous operation.</returns>
        protected internal override IAsyncResult BeginInvoke(AsyncCallback callback, object state)
        {
            return _action.BeginInvoke(_arg1, _arg2, callback, state);
        }

        /// <summary>
        /// Ends an asynchronous operation.
        /// </summary>
        /// <param name="asyncResult">The status of this asynchronous operation.</param>
        /// <returns>Completion status of the operation.</returns>
        protected internal override WorkCompletionStatus EndInvoke(IAsyncResult asyncResult)
        {
            _action.EndInvoke(asyncResult);
            return WorkCompletionStatus.Successful;
        }

        /// <summary>
        /// Executes the operation.
        /// </summary>
        /// <returns>Completion status of the operation.</returns>
        protected internal override WorkCompletionStatus Invoke()
        {
            _action.Invoke(_arg1, _arg2);
            return WorkCompletionStatus.Successful;
        }
    }

    /// <summary>
    /// Represents an operation which does not return any result upon completion.
    /// </summary>
    /// <typeparam name="T1">The type of the first argument.</typeparam>
    /// <typeparam name="T2">The type of the second argument.</typeparam>
    /// <typeparam name="T3">The type of the third argument.</typeparam>
    public class Work<T1, T2, T3> : Job<WorkCompletionStatus>
    {
        private readonly Action<T1, T2, T3> _action;
        private readonly T1 _arg1;
        private readonly T2 _arg2;
        private readonly T3 _arg3;

        /// <summary>
        /// Initializes a new instance of the <see cref="Work&lt;T1, T2, T3&gt;"/> class.
        /// </summary>
        /// <param name="action">The action to run.</param>
        /// <param name="arg1">The first argument.</param>
        /// <param name="arg2">The second argument.</param>
        /// <param name="arg3">The third argument.</param>
        public Work(Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3)
        {
            _action = action;
            _arg1 = arg1;
            _arg2 = arg2;
            _arg3 = arg3;
        }

        /// <summary>
        /// Begins an asynchronous operation.
        /// </summary>
        /// <param name="callback">The <see cref="AsyncCallback"/> delegate.</param>
        /// <param name="state">The state object for this operation.</param>
        /// <returns>The status of the asynchronous operation.</returns>
        protected internal override IAsyncResult BeginInvoke(AsyncCallback callback, object state)
        {
            return _action.BeginInvoke(_arg1, _arg2, _arg3, callback, state);
        }

        /// <summary>
        /// Ends an asynchronous operation.
        /// </summary>
        /// <param name="asyncResult">The status of this asynchronous operation.</param>
        /// <returns>Completion status of the operation.</returns>
        protected internal override WorkCompletionStatus EndInvoke(IAsyncResult asyncResult)
        {
            _action.EndInvoke(asyncResult);
            return WorkCompletionStatus.Successful;
        }

        /// <summary>
        /// Executes the operation.
        /// </summary>
        /// <returns>Completion status of the operation.</returns>
        protected internal override WorkCompletionStatus Invoke()
        {
            _action.Invoke(_arg1, _arg2, _arg3);
            return WorkCompletionStatus.Successful;
        }
    }

    /// <summary>
    /// Represents an operation which does not return any result upon completion.
    /// </summary>
    /// <typeparam name="T1">The type of the first argument.</typeparam>
    /// <typeparam name="T2">The type of the second argument.</typeparam>
    /// <typeparam name="T3">The type of the third argument.</typeparam>
    /// <typeparam name="T4">The type of the fourth argument.</typeparam>
    public class Work<T1, T2, T3, T4> : Job<WorkCompletionStatus>
    {
        private readonly Action<T1, T2, T3, T4> _action;
        private readonly T1 _arg1;
        private readonly T2 _arg2;
        private readonly T3 _arg3;
        private readonly T4 _arg4;

        /// <summary>
        /// Initializes a new instance of the <see cref="Work&lt;T1, T2, T3, T4&gt;"/> class.
        /// </summary>
        /// <param name="action">The action to run.</param>
        /// <param name="arg1">The first argument.</param>
        /// <param name="arg2">The second argument.</param>
        /// <param name="arg3">The third argument.</param>
        /// <param name="arg4">The fourth argument.</param>
        public Work(Action<T1, T2, T3, T4> action, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
        {
            _action = action;
            _arg1 = arg1;
            _arg2 = arg2;
            _arg3 = arg3;
            _arg4 = arg4;
        }

        /// <summary>
        /// Begins an asynchronous operation.
        /// </summary>
        /// <param name="callback">The <see cref="AsyncCallback"/> delegate.</param>
        /// <param name="state">The state object for this operation.</param>
        /// <returns>The status of the asynchronous operation.</returns>
        protected internal override IAsyncResult BeginInvoke(AsyncCallback callback, object state)
        {
            return _action.BeginInvoke(_arg1, _arg2, _arg3, _arg4, callback, state);
        }

        /// <summary>
        /// Ends an asynchronous operation.
        /// </summary>
        /// <param name="asyncResult">The status of this asynchronous operation.</param>
        /// <returns>Completion status of the operation.</returns>
        protected internal override WorkCompletionStatus EndInvoke(IAsyncResult asyncResult)
        {
            _action.EndInvoke(asyncResult);
            return WorkCompletionStatus.Successful;
        }

        /// <summary>
        /// Executes the operation.
        /// </summary>
        /// <returns>Completion status of the operation.</returns>
        protected internal override WorkCompletionStatus Invoke()
        {
            _action.Invoke(_arg1, _arg2, _arg3, _arg4);
            return WorkCompletionStatus.Successful;
        }
    }
}